// SPDX-License-Identifier: GPL-2.0+
/*
 *  Startup Code for MIPS32 XBURST CPU-core
 *
 *  Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc>
 */

#include <config.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/cacheops.h>
#include <asm/cache.h>
#include <mach/jz4780.h>

	.set noreorder

	.globl _start
	.text
_start:
#ifdef CONFIG_SPL_BUILD
#if defined(CONFIG_SPL_MMC_SUPPORT) || defined(CONFIG_SPL_JZMMC_SUPPORT)

	/* magic value ("MSPL") */
	.word 0x4d53504c

#if defined(CONFIG_SOC_X1000) || defined(CONFIG_SOC_X1830) || defined(CONFIG_SOC_X2000)
	.space 2044, 0
#endif

#elif CONFIG_SPL_SFC_NOR
	.word 0x03040506
	.word 0x55aa5502
	.word 0xffff00aa
	.word 0x00000000
	#ifdef CONFIG_SPL_VERSION
		.word (0x00000000 | CONFIG_SPL_VERSION)
		.space (512-20),0
	#else
		.space (512-16),0
	#endif
	.space 1536, 0
#endif /* !CONFIG_SPL_MMC_SUPPORT */

#ifndef CONFIG_SOC_X2000
	/* Invalidate BTB */
	mfc0	t0, CP0_CONFIG, 7
	nop
	ori	t0, 2
	mtc0	t0, CP0_CONFIG, 7
	nop
#endif

#ifdef CONFIG_SOC_X1830
    mfc0	v0, $12, 2
    nop
    li	v1, 0x7fffffff
    and	v0, v0, v1
    mtc0	v0, $12, 2
    nop
#endif

	/*
	 * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
	 */
	li	t0, 0x0040FC04
	mtc0	t0, CP0_STATUS

	/* CAUSE register */
	/* IV=1, use the specical interrupt vector (0x200) */
	li	t1, 0x00800000
	mtc0	t1, CP0_CAUSE

#if defined(CONFIG_SOC_JZ4775) || defined(CONFIG_SOC_JZ4780) || defined(CONFIG_SOC_X1000)
	/* enable bridge radical mode */
	la	t0, CPM_BASE
	lw	t1, 0x24(t0)
	ori	t1, t1, 0x22
	sw	t1, 0x24(t0)
#endif

	.set push
	.set	mips32

#if defined(CONFIG_SOC_JZ4775) || defined(CONFIG_SOC_JZ4780) || defined(CONFIG_SOC_X1000)
	/* enable idx-store-data cache insn */
	li      t0, 0x20000000
	mtc0    t0, CP0_ECC

	mtc0	zero, CP0_TAGLO
	mtc0	zero, CP0_TAGHI

	li	t0, KSEG0
	addu	t1, t0, CONFIG_SYS_DCACHE_SIZE
1:
	cache	INDEX_STORE_TAG_D, 0(t0)
	bne	t0, t1, 1b
	addiu	t0, t0, CONFIG_SYS_CACHELINE_SIZE

	li	t0, KSEG0
	addu	t1, t0, CONFIG_SYS_ICACHE_SIZE
2:
	cache	INDEX_STORE_TAG_I, 0(t0)
	bne	t0, t1, 2b
	addiu	t0, t0, CONFIG_SYS_CACHELINE_SIZE

	/* Invalidate BTB */
	mfc0	t0, CP0_CONFIG, 7
	nop
	ori	t0, 2
	mtc0	t0, CP0_CONFIG, 7
	nop
#endif

	/* Enable caches */
	li	t0, CONF_CM_CACHABLE_NONCOHERENT
	mtc0	t0, CP0_CONFIG
	nop

	sync
	nop

	.set pop

	/* Set up stack */
	li	sp, CONFIG_SPL_STACK

	b		board_init_f
	 nop

#if defined(CONFIG_SOC_JZ4775) || defined(CONFIG_SOC_JZ4780) || defined(CONFIG_SOC_X1000)

	.globl enable_caches
	.ent enable_caches
enable_caches:
	/* enable idx-store-data cache insn */
	li      t0, 0x20000000
	mtc0    t0, CP0_ECC

	mtc0	zero, CP0_TAGLO
	mtc0	zero, CP0_TAGHI

	li	t0, KSEG0
	addu	t1, t0, CONFIG_SYS_DCACHE_SIZE
1:
	cache	INDEX_STORE_TAG_D, 0(t0)
	bne	t0, t1, 1b
	addiu	t0, t0, CONFIG_SYS_CACHELINE_SIZE

	li	t0, KSEG0
	addu	t1, t0, CONFIG_SYS_ICACHE_SIZE
2:
	cache	INDEX_STORE_TAG_I, 0(t0)
	bne	t0, t1, 2b
	addiu	t0, t0, CONFIG_SYS_CACHELINE_SIZE

	/* Invalidate BTB */
	mfc0	t0, CP0_CONFIG, 7
	nop
	ori	t0, 2
	mtc0	t0, CP0_CONFIG, 7
	nop

	/* Enable caches */
	li	t0, CONF_CM_CACHABLE_NONCOHERENT
	mtc0	t0, CP0_CONFIG
	nop

	jr	ra
	 nop

	.end enable_caches

#endif /* CONFIG_SOC_JZ4780 */
#endif /* !CONFIG_SPL_BUILD */
